class Travel {
    constructor(travelDetail, lastTravel, timeout) {
        if (travelDetail && travelDetail.event) {
            this.target = travelDetail.event.target;
            this.type = travelDetail.type;
        }
        this.lastTravel = lastTravel;
        this.travelDetail = travelDetail;
        this.startTime = Date.now();
        this.duration = 0;
        this.timeout = timeout || 500;
        this.hasDisposed = false;
        this.timer = null;
        this.start();
    }

    isEqualToLast() {
        return this.lastTravel && this.lastTravel.type === this.type && this.lastTravel.travelDetail && this.travelDetail.event.target === this.lastTravel.travelDetail.event.target;
    }

    start() {
        if (this.isEqualToLast()) {
            !this.lastTravel.hasDisposed && clearTimeout(this.lastTravel.timer);
            this.duration = this.duration + this.startTime - this.lastTravel.startTime;
            if (this.lastTravel.lastTravel) {
                this.lastTravel = this.lastTravel.lastTravel;
            }
        } else {
            let hasLastTravel = this.lastTravel;
            hasLastTravel && !this.lastTravel.hasDisposed && (this.lastTravel._end(this.lastTravel.getData()), this.lastTravel.log());
        }
        this.timer = setTimeout(() => {
            this._end(this.getData());
        }, this.timeout);
        return this;
    }

    log() {
        console.log('[log---]%s操作结束持续时间为%d', this.type, this.duration);
    }

    getData() {
        if ((!this.travelDetail || !this.target) && !this.data) {
            return {};
        }
        if (!this.data) {
            let target = this.target;
            let event = this.travelDetail.event;
            this.data = {
                type: event.type,
                nodeType: target.nodeName,
                targetNode: {
                    id: target.id,
                    className: target.class,
                    name: target.name
                },
                time: this.startTime,
                duration: this.duration,
                value: target.value,
                e: {
                    clientX: event.clientX,
                    clientY: event.clientY,
                    layerX: event.layerX,
                    layerY: event.layerY,
                    movementX: event.movementX,
                    movementY: event.movementY,
                    offsetX: event.offsetX,
                    offsetY: event.offsetY,
                    pageX: event.pageX,
                    pageY: event.pageY,
                    screenX: event.screenX,
                    screenY: event.screenY,
                    x: event.x,
                    y: event.y
                }
            };
        }
        return this.data;
    }

    dispose() {
        clearTimeout(this.timeout);
        this.hasDisposed = true;
        this.travelDetail = null;
        this.lastTravel = null;
    }

    _end(...args) {
        this.log();
        this.getData();
        this.end.apply(this, args);
        this.dispose();
    }

    end({
        target,
        time
    }) {
        console.log('目标是:', target, ',时间为:', time);
        return this;
    }

}

export default Travel;


export class ChangeTravel extends Travel {
    constructor(travelDetail, lastTravel) {
        super(travelDetail, lastTravel);
    }
    end({
        targetNode,
        value,
        time
    }) {
        console.log('触发了change事件,作用在', targetNode, '上最终的输入框值为', value);
    }
}

export class InputTravel extends Travel {
    constructor(travelDetail, lastTravel) {
        super(travelDetail, lastTravel);
    }
    end({
        targetNode,
        value,
        time
    }) {
        console.log('触发了input事件,作用在', targetNode, '上上最终的输入框值为', value);
    }
}

export class ClickTravel extends Travel {
    constructor(travelDetail, lastTravel) {
        super(travelDetail, lastTravel);
    }
    end({
        targetNode,
        time
    }) {
        console.log('在%d触发了click事件,作用在', time, targetNode);
    }
}

export class MouseTravel extends Travel {
    constructor(travelDetail, lastTravel) {
        super(travelDetail, lastTravel);
    }
    end({
        targetNode,
        time
    }) {
        console.log('在%d触发了mouse事件,作用在', time, targetNode);
    }
}

export class WheelTravel extends Travel {
    constructor(travelDetail, lastTravel) {
        super(travelDetail, lastTravel);
    }
    end({
        targetNode,
        time
    }) {
        console.log('在%d触发了wheel事件,作用在', time, targetNode);
    }
}